/**************************************************************************************
*
*	Copyright (C) 2009 - 2012 Brent Andrew O. Chua - See LICENSE.txt for more info.
*		
*	Filename	-	CSCameraControlFreeRoam.cpp
*
*	Comments	-	See CSCameraControlFreeRoam.h
*
**************************************************************************************/
#include "../Include/CSCameraControlFreeRoam.h"
#include "../Include/Actor.h"
#include "../Include/Scene.h"
#include "../Include/WindowView.h"
#include "../Include/EventInputs.h"
#include "../Include/InputSystem.h"

namespace Pulse
{
	// This is defined for each derived native script class.
	const StringID CSCameraControlFreeRoam::m_scriptTypeID( PSX_String("Camera Control Free Roam") );

	CSCameraControlFreeRoam::CSCameraControlFreeRoam( ComponentNativeScript *pComponentOwner )
		: INativeScript( pComponentOwner )
	{

	}

	CSCameraControlFreeRoam::~CSCameraControlFreeRoam( void )
	{

	}

	EErrorCode::Type CSCameraControlFreeRoam::OnScriptInitialize( void )
	{
		m_bMove = FALSE;
		m_bKeyW = m_bKeyA = m_bKeyS = m_bKeyD = m_bKeyQ = m_bKeyE = FALSE;
		m_moveSpeed = 10.0f;
		m_rotationSpeed = 0.35f;
		m_speed = Vector3::ZERO_VECTOR;
		m_rotation = Vector3::ZERO_VECTOR;


		EventSystem *pEventSys = this->m_pScriptComponent->GetOwnerUnsafe()->GetScene()->GetWindowViewOwner()->GetEventSystem();

		pEventSys->AddListener( EEvent::INPUT_KEY_UP, this, &CSCameraControlFreeRoam::OnKeyUp );
		pEventSys->AddListener( EEvent::INPUT_KEY_DOWN, this, &CSCameraControlFreeRoam::OnKeyDown );
		pEventSys->AddListener( EEvent::INPUT_MOUSE_MOVE, this, &CSCameraControlFreeRoam::OnMouseMove );
		pEventSys->AddListener( EEvent::INPUT_MOUSE_BUTTONUP, this, &CSCameraControlFreeRoam::OnMouseButtonUp );
		pEventSys->AddListener( EEvent::INPUT_MOUSE_BUTTONDOWN, this, &CSCameraControlFreeRoam::OnMouseButtonDown );

		return EErrorCode::OKAY;
	}

	void CSCameraControlFreeRoam::OnScriptDestroy( void )
	{
		EventSystem *pEventSys = this->m_pScriptComponent->GetOwnerUnsafe()->GetScene()->GetWindowViewOwner()->GetEventSystem();

		pEventSys->RemoveListener( EEvent::INPUT_KEY_UP, this, &CSCameraControlFreeRoam::OnKeyUp );
		pEventSys->RemoveListener( EEvent::INPUT_KEY_DOWN, this, &CSCameraControlFreeRoam::OnKeyDown );
		pEventSys->RemoveListener( EEvent::INPUT_MOUSE_MOVE, this, &CSCameraControlFreeRoam::OnMouseMove );
		pEventSys->RemoveListener( EEvent::INPUT_MOUSE_BUTTONUP, this, &CSCameraControlFreeRoam::OnMouseButtonUp );
		pEventSys->RemoveListener( EEvent::INPUT_MOUSE_BUTTONDOWN, this, &CSCameraControlFreeRoam::OnMouseButtonDown );
	}

	void CSCameraControlFreeRoam::OnScriptUpdate( FLOAT dt )
	{
		Actor *pActor = m_pScriptComponent->GetOwnerUnsafe();
		Matrix4x4 *pTransform = pActor->GetTransformLocal();

		//// Set orientation
		//pActor->SetRotationX( m_rotation.x * (PSX_PI / 180.0f) );
		//pActor->SetRotationY( m_rotation.y * (PSX_PI / 180.0f) );


		// Set translation
		if ( FALSE && m_speed != Vector3::ZERO_VECTOR )
		{
			Vector3 newPosition = Vector3::ZERO_VECTOR;
		
			newPosition = newPosition + pTransform->GetTranslation();
			newPosition += (pTransform->GetRight() * m_speed.x * dt);
			newPosition += (pTransform->GetUp() * m_speed.y * dt);
			newPosition += (pTransform->GetForward() * m_speed.z * dt);
			
			pActor->SetPosition( &newPosition );
		}

		if ( m_bMove )
		{
			m_speed = Vector3::ZERO_VECTOR;

			if ( m_bKeyW )
				m_speed.z += m_moveSpeed;

			if ( m_bKeyS )
				m_speed.z -= m_moveSpeed;

			if ( m_bKeyA )
				m_speed.x -= m_moveSpeed;

			if ( m_bKeyD )
				m_speed.x += m_moveSpeed;

			if ( m_bKeyQ )
				m_speed.y -= m_moveSpeed;

			if ( m_bKeyE )
				m_speed.y += m_moveSpeed;

			Vector3 newPosition = Vector3::ZERO_VECTOR;

			newPosition = newPosition + pTransform->GetTranslation();
			newPosition += (pTransform->GetRight() * m_speed.x * dt);
			newPosition += (pTransform->GetUp() * m_speed.y * dt);
			newPosition += (pTransform->GetForward() * m_speed.z * dt);

			pActor->SetPosition( &newPosition );

		}
	}

	void CSCameraControlFreeRoam::OnKeyUp( IEvent *pEvent )
	{
		EventKeyUp *pDerivedEvent = (EventKeyUp*)pEvent;
		
		if ( m_bMove == FALSE )
			return;

		if ( pDerivedEvent->GetKey() == PIK_W )
		{
			m_bKeyW = FALSE;
			//m_speed.z -= m_moveSpeed;
		}
		else if ( pDerivedEvent->GetKey() == PIK_S )
		{
			m_bKeyS = FALSE;
			//m_speed.z -= -m_moveSpeed;

		}
		else if ( pDerivedEvent->GetKey() == PIK_A )
		{
			m_bKeyA = FALSE;
			//m_speed.x -= -m_moveSpeed;

		}
		else if ( pDerivedEvent->GetKey() == PIK_D )
		{
			m_bKeyD = FALSE;
			//m_speed.x -= m_moveSpeed;
		}
		else if ( pDerivedEvent->GetKey() == PIK_Q )
		{
			m_bKeyQ = FALSE;
			//m_speed.y -= -m_moveSpeed;
		}
		else if ( pDerivedEvent->GetKey() == PIK_E )
		{
			m_bKeyE = FALSE;
			//m_speed.y -= m_moveSpeed;
		}		

	}

	void CSCameraControlFreeRoam::OnKeyDown( IEvent *pEvent )
	{
		EventKeyDown *pDerivedEvent = (EventKeyDown*)pEvent;

		if ( m_bMove == FALSE )
			return;

		if ( pDerivedEvent->GetKey() == PIK_W )
		{
			m_bKeyW = TRUE;
			//m_speed.z = m_moveSpeed;
		}
		else if ( pDerivedEvent->GetKey() == PIK_S )
		{
			m_bKeyS = TRUE;
			//m_speed.z += -m_moveSpeed;
		}
		else if ( pDerivedEvent->GetKey() == PIK_A )
		{
			m_bKeyA = TRUE;
			//m_speed.x += -m_moveSpeed;
		}
		else if ( pDerivedEvent->GetKey() == PIK_D )
		{
			m_bKeyD = TRUE;
			//m_speed.x += m_moveSpeed;
		}
		else if ( pDerivedEvent->GetKey() == PIK_Q )
		{
			m_bKeyQ = TRUE;
			//m_speed.y += -m_moveSpeed;
		}
		else if ( pDerivedEvent->GetKey() == PIK_E )
		{
			m_bKeyE = TRUE;
			//m_speed.y += m_moveSpeed;
		}
	}

	void CSCameraControlFreeRoam::OnMouseMove( IEvent *pEvent )
	{
		EventMouseMove *pDerivedEvent = (EventMouseMove*)pEvent;

		if ( m_bMove )
		{
			Actor *pActor = m_pScriptComponent->GetOwnerUnsafe();
			Matrix4x4 *pTransform = pActor->GetTransformLocal();

			// Set orientation
			Vector3 newRotation = *pActor->GetRotation();
		
			newRotation.x += pDerivedEvent->GetDeltaY() * (PSX_PI / 180.0f) * m_rotationSpeed; 
			newRotation.y += pDerivedEvent->GetDeltaX() * (PSX_PI / 180.0f) * m_rotationSpeed; 
	
			pActor->SetRotation( &newRotation );
		}
	}

	void CSCameraControlFreeRoam::OnMouseButtonUp( IEvent *pEvent )
	{
		EventMouseButtonUp *pDerivedEvent = (EventMouseButtonUp*)pEvent;

		if ( pDerivedEvent->GetMouseButton() == EMouseButton::RIGHT_BUTTON )
		{
			m_bMove = FALSE;
			m_bKeyW = m_bKeyA = m_bKeyS = m_bKeyD = m_bKeyQ = m_bKeyE = FALSE;
			m_speed = Vector3::ZERO_VECTOR;
		}

	}

	void CSCameraControlFreeRoam::OnMouseButtonDown( IEvent *pEvent )
	{
		EventMouseButtonDown *pDerivedEvent = (EventMouseButtonDown*)pEvent;
	
		if ( pDerivedEvent->GetMouseButton() == EMouseButton::RIGHT_BUTTON )
		{
			m_bMove = TRUE;
		}
	}
}